from bs4 import BeautifulSoup
import json
import re


def parse_production_formula(html_content):
    """
    解析生产配方 HTML 结构
    """
    soup = BeautifulSoup(html_content, 'html.parser')

    # 查找所有 formula 元素
    formula_elements = soup.find_all(class_='formula')

    recipes = []

    for formula in formula_elements:
        recipe = parse_single_formula(formula)
        if recipe:
            recipes.append(recipe)

    return recipes


def parse_single_formula(formula_element):
    """
    解析单个 formula 元素
    """
    # 查找所有 icon-background 元素
    icon_backgrounds = formula_element.find_all(class_='icon-background')

    # 查找 formula-arrow 元素
    formula_arrow = formula_element.find(class_='formula-arrow')

    if not formula_arrow or not icon_backgrounds:
        return None

    # 确定原材料和产物的分界点
    arrow_index = None
    for i, child in enumerate(formula_element.children):
        if hasattr(child, 'get') and 'formula-arrow' in child.get('class', []):
            arrow_index = i
            break

    if arrow_index is None:
        return None

    # 解析原材料（arrow 之前的部分）
    ingredients = []
    for i, icon in enumerate(icon_backgrounds):
        if i < arrow_index:
            ingredient = parse_icon_background(icon)
            if ingredient:
                ingredients.append(ingredient)

    # 解析产物（arrow 之后的部分）
    products = []
    for i, icon in enumerate(icon_backgrounds):
        if i >= arrow_index:
            product = parse_icon_background(icon)
            if product:
                products.append(product)

    # 解析生产信息
    production_info = parse_formula_arrow(formula_arrow)

    if not products:
        return None

    # 构建配方数据（假设第一个产物为主要产物）
    main_product = products[0]

    recipe = {
        "name": main_product["name"],
        "mount": main_product["mount"],
        "machine": production_info["device"],
        "needs": ingredients,
        "time": production_info["time"]
    }

    return recipe


def parse_icon_background(icon_element):
    """
    解析 icon-background 元素，获取物品名称和数量
    """
    try:
        # 获取物品名称（从 a 标签的 title 属性）
        a_tag = icon_element.find('a')
        if not a_tag:
            return None

        item_name = a_tag.get('title', '').strip()
        if not item_name:
            return None

        # 获取物品数量（从 icon-num 元素）
        icon_num = icon_element.find(class_='icon-num')
        if icon_num:
            mount_text = icon_num.get_text(strip=True)
            # 处理数量文本，移除可能的非数字字符
            mount = int(re.sub(r'[^\d]', '', mount_text)) if mount_text else 1
        else:
            mount = 1

        return {
            "name": item_name,
            "mount": mount
        }

    except (ValueError, AttributeError):
        return None


def parse_formula_arrow(arrow_element):
    """
    解析 formula-arrow 元素，获取生产时间和设备
    """
    production_info = {
        "time": 0,
        "device": "未知设备"
    }

    try:
        # 解析生产时间
        time_element = arrow_element.find(class_='formula-arrow-time')
        if time_element:
            time_text = time_element.get_text(strip=True)
            # 提取数字部分，处理单位（s, m, h 等）
            time_match = re.search(r'(\d+)\s*[smh]?', time_text)
            if time_match:
                production_info["time"] = int(time_match.group(1))

        # 解析生产设备
        device_element = arrow_element.find(class_='formula-arrow-device')
        if device_element:
            device_text = device_element.get_text(strip=True)
            production_info["device"] = device_text

    except (ValueError, AttributeError):
        pass

    return production_info


def process_html_file(filename):
    """
    从 HTML 文件读取并解析配方
    """
    try:
        with open(filename, 'r', encoding='utf-8') as file:
            html_content = file.read()

        recipes = parse_production_formula(html_content)
        return recipes

    except Exception as e:
        print(f"读取文件时出错: {e}")
        return []


def save_recipes_to_json(recipes, filename):
    """
    将配方数据保存为 JSON 文件
    """
    try:
        with open(filename, 'w', encoding='utf-8') as file:
            json.dump(recipes, file, ensure_ascii=False, indent=2)
        print(f"配方数据已保存到: {filename}")
        return True
    except Exception as e:
        print(f"保存文件时出错: {e}")
        return False


# 测试代码
if __name__ == "__main__":
    # 示例 HTML（使用您提供的结构）
    example_html = """
<span class="formula">
    <span class="icon-background icon-normal">
        <a href="/dsp/%E5%BC%95%E5%8A%9B%E9%80%8F%E9%95%9C" title="引力透镜">
            <img alt="引力透镜" data-file-height="80" data-file-width="80" decoding="async" height="40" loading="lazy" src="https://patchwiki.biligame.com/images/dsp/thumb/0/01/kfaaftqfpcw8uk9j6ia2o2c7taeaxqc.png/40px-%E5%BC%95%E5%8A%9B%E9%80%8F%E9%95%9C.png" srcset="https://patchwiki.biligame.com/images/dsp/thumb/0/01/kfaaftqfpcw8uk9j6ia2o2c7taeaxqc.png/60px-%E5%BC%95%E5%8A%9B%E9%80%8F%E9%95%9C.png 1.5x, https://patchwiki.biligame.com/images/dsp/0/01/kfaaftqfpcw8uk9j6ia2o2c7taeaxqc.png 2x" width="40"/>
        </a>
        <span class="icon-num">1</span>
    </span><span class="icon-background icon-normal">
    <a href="/dsp/%E9%87%8F%E5%AD%90%E8%8A%AF%E7%89%87" title="量子芯片">
        <img alt="量子芯片" data-file-height="80" data-file-width="80" decoding="async" height="40" loading="lazy" src="https://patchwiki.biligame.com/images/dsp/thumb/d/d5/qy5or094fnwpnh8sv5stdl5yda2w8i6.png/40px-%E9%87%8F%E5%AD%90%E8%8A%AF%E7%89%87.png" srcset="https://patchwiki.biligame.com/images/dsp/thumb/d/d5/qy5or094fnwpnh8sv5stdl5yda2w8i6.png/60px-%E9%87%8F%E5%AD%90%E8%8A%AF%E7%89%87.png 1.5x, https://patchwiki.biligame.com/images/dsp/d/d5/qy5or094fnwpnh8sv5stdl5yda2w8i6.png 2x" width="40"/>
    </a>
    <span class="icon-num">1</span></span><span class="formula-arrow">
    <span class="formula-arrow-img">
        <img alt="箭头.png" data-file-height="185" data-file-width="185" decoding="async" height="40" loading="lazy" src="https://patchwiki.biligame.com/images/dsp/thumb/d/db/s0wqua49dpayfuni489466z5edcsard.png/40px-%E7%AE%AD%E5%A4%B4.png" srcset="https://patchwiki.biligame.com/images/dsp/thumb/d/db/s0wqua49dpayfuni489466z5edcsard.png/60px-%E7%AE%AD%E5%A4%B4.png 1.5x, https://patchwiki.biligame.com/images/dsp/thumb/d/db/s0wqua49dpayfuni489466z5edcsard.png/80px-%E7%AE%AD%E5%A4%B4.png 2x" width="40"/></span><span class="formula-arrow-time" style="padding-right: 8px;">24s</span><span class="formula-arrow-device" style="padding-right: 8px;"><a class="mw-redirect" href="/dsp/%E7%A7%91%E7%A0%94%E8%AE%BE%E5%A4%87" title="科研设备">科研</a></span></span><span class="icon-background icon-normal"><a href="/dsp/%E5%BC%95%E5%8A%9B%E7%9F%A9%E9%98%B5" title="引力矩阵"><img alt="引力矩阵" data-file-height="80" data-file-width="80" decoding="async" height="40" loading="lazy" src="https://patchwiki.biligame.com/images/dsp/thumb/4/44/ss54aeumnmk374ni560ovd11qlysjlf.png/40px-%E5%BC%95%E5%8A%9B%E7%9F%A9%E9%98%B5.png" srcset="https://patchwiki.biligame.com/images/dsp/thumb/4/44/ss54aeumnmk374ni560ovd11qlysjlf.png/60px-%E5%BC%95%E5%8A%9B%E7%9F%A9%E9%98%B5.png 1.5x, https://patchwiki.biligame.com/images/dsp/4/44/ss54aeumnmk374ni560ovd11qlysjlf.png 2x" width="40"/>
</a>
    <span class="icon-num">2</span>
</span>
</span>
    """

    # 解析示例 HTML
    recipes = parse_production_formula(example_html)

    if recipes:
        print("解析结果:")
        print(json.dumps(recipes, ensure_ascii=False, indent=2))

        # 保存到文件
        save_recipes_to_json(recipes, 'production_recipes.json')
    else:
        print("未找到配方数据")